package com.example.backend.service;

import com.example.backend.domain.entity.User;
import com.example.backend.domain.enums.Role;
import com.example.backend.domain.enums.UserStatus;
import com.example.backend.dto.LoginRequest;
import com.example.backend.dto.LoginResponse;
import com.example.backend.dto.RegisterRequest;
import com.example.backend.dto.UserDto;
import com.example.backend.exception.BusinessException;
import com.example.backend.util.JwtUtil;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.List;

@Service
public class AuthService {
    private final UserService userService;
    private final JwtUtil jwtUtil;
    private final PasswordEncoder passwordEncoder;

    public AuthService(UserService userService, JwtUtil jwtUtil, PasswordEncoder passwordEncoder) {
        this.userService = userService;
        this.jwtUtil = jwtUtil;
        this.passwordEncoder = passwordEncoder;
    }

    public UserDto register(RegisterRequest request) {
        System.out.println("=== AuthService.register 开始 ===");
        System.out.println("接收到的注册请求: " + request);
        
        // 验证密码确认
        if (!request.getPassword().equals(request.getConfirmPassword())) {
            System.out.println("密码验证失败: 两次输入的密码不一致");
            throw new BusinessException("两次输入的密码不一致");
        }
        
        // 检查用户名是否已存在
        System.out.println("检查用户名是否已存在: " + request.getUsername());
        if (userService.existsByUsername(request.getUsername())) {
            System.out.println("用户名已存在: " + request.getUsername());
            throw new BusinessException("用户名已存在");
        }
        System.out.println("用户名可用: " + request.getUsername());
        
        // 检查邮箱是否已存在
        System.out.println("检查邮箱是否已存在: " + request.getEmail());
        if (userService.existsByEmail(request.getEmail())) {
            System.out.println("邮箱已被注册: " + request.getEmail());
            throw new BusinessException("邮箱已被注册");
        }
        System.out.println("邮箱可用: " + request.getEmail());
        
        // 验证角色
        System.out.println("验证用户角色: " + request.getRole());
        Role role;
        try {
            role = Role.valueOf(request.getRole().toUpperCase());
            System.out.println("角色验证通过: " + role);
        } catch (IllegalArgumentException e) {
            System.out.println("角色验证失败: " + request.getRole());
            throw new BusinessException("无效的用户角色");
        }
        
        // 创建新用户
        System.out.println("开始创建用户对象...");
        User user = User.builder()
                .username(request.getUsername())
                .password(passwordEncoder.encode(request.getPassword()))
                .fullName(request.getFullName())
                .email(request.getEmail())
                .phone(request.getPhone())
                .department(request.getDepartment())
                .position(request.getPosition())
                .employeeId(request.getEmployeeId())
                .role(role)
                .status(UserStatus.ACTIVE)
                .loginCount(0)
                .build();
        
        System.out.println("用户对象创建完成: " + user.getUsername());
        
        // 保存用户
        System.out.println("开始保存用户到数据库...");
        User savedUser = userService.save(user);
        System.out.println("用户保存成功，ID: " + savedUser.getId());
        
        // 转换为DTO
        System.out.println("开始转换为UserDto...");
        UserDto userDto = convertToUserDto(savedUser);
        System.out.println("转换完成");
        
        System.out.println("=== AuthService.register 结束 ===");
        return userDto;
    }

    public LoginResponse login(LoginRequest request) {
        User user = userService.findByUsername(request.getUsername())
                .orElseThrow(() -> new BusinessException("用户名或密码错误"));

        // 检查用户状态（管理员可以绕过状态检查，防止管理员账户被误禁）
        if (user.getStatus() != null && user.getStatus() != UserStatus.ACTIVE) {
            // 管理员账户始终允许登录，防止管理员被误禁导致无法恢复
            if (user.getRole() != Role.ADMIN) {
                throw new BusinessException("账户已被禁用，请联系管理员");
            } else {
                // 管理员账户被误禁，自动恢复为ACTIVE状态
                user.setStatus(UserStatus.ACTIVE);
                userService.update(user);
            }
        }

        // 密码验证（支持明文和加密密码）
        boolean passwordValid = false;
        if (user.getPassword().startsWith("$2a$") || user.getPassword().startsWith("$2b$")) {
            // 加密密码
            passwordValid = passwordEncoder.matches(request.getPassword(), user.getPassword());
        } else {
            // 明文密码（兼容旧数据）
            passwordValid = user.getPassword().equals(request.getPassword());
        }

        if (!passwordValid) {
            throw new BusinessException("用户名或密码错误");
        }

        // 更新最后登录时间和登录次数
        user.setLastLoginAt(Instant.now());
        user.setLoginCount((user.getLoginCount() != null ? user.getLoginCount() : 0) + 1);
        userService.update(user);

        String token = jwtUtil.generateToken(user.getUsername(), user.getId(), user.getRole().name().toLowerCase());
        Instant expiresAt = Instant.now().plusSeconds(86400); // 24小时后过期
        
        return LoginResponse.builder()
                .token(token)
                .tokenType("Bearer")
                .userId(user.getId())
                .username(user.getUsername())
                .fullName(user.getFullName())
                .email(user.getEmail())
                .role(user.getRole().name().toLowerCase()) // 返回小写角色名称
                .expiresAt(expiresAt)
                .expiresIn(86400L)
                .build();
    }

    public User validateToken(String token) {
        return jwtUtil.validateToken(token);
    }

    public UserDto getCurrentUser(String token) {
        User user = validateToken(token);
        return convertToUserDto(user);
    }

    public List<String> getUserPermissions(String token) {
        User user = validateToken(token);
        return getUserPermissionsByRole(user.getRole().name());
    }

    private List<String> getUserPermissionsByRole(String role) {
        return switch (role.toUpperCase()) {
            case "ADMIN" -> List.of(
                "user:read", "user:write", "user:delete", "user:manage",
                "ticket:read", "ticket:write", "ticket:delete", "ticket:assign", "ticket:manage",
                "feedback:read", "feedback:write", "feedback:delete", "feedback:manage",
                "comment:read", "comment:write", "comment:delete", "comment:manage",
                "statistics:read", "statistics:manage",
                "system:config", "system:log", "system:manage",
                "dashboard:read", "dashboard:manage"
            );
            case "SUPERVISOR" -> List.of(
                "user:read", "user:write",
                "ticket:read", "ticket:write", "ticket:assign", "ticket:manage",
                "feedback:read", "feedback:write", "feedback:manage",
                "comment:read", "comment:write", "comment:manage",
                "statistics:read", "statistics:manage",
                "dashboard:read"
            );
            case "AGENT" -> List.of(
                "ticket:read", "ticket:write", "ticket:assign",
                "feedback:read", "feedback:write",
                "comment:read", "comment:write",
                "user:read",
                "dashboard:read"
            );
            case "CUSTOMER" -> List.of(
                "ticket:read", "ticket:write",
                "feedback:read", "feedback:write",
                "comment:read", "comment:write",
                "dashboard:read"
            );
            case "READONLY" -> List.of(
                "ticket:read",
                "feedback:read",
                "comment:read",
                "user:read",
                "statistics:read",
                "dashboard:read"
            );
            default -> List.of("dashboard:read"); // 默认权限
        };
    }

    private UserDto convertToUserDto(User user) {
        return UserDto.builder()
                .id(user.getId())
                .username(user.getUsername())
                .fullName(user.getFullName())
                .email(user.getEmail())
                .phone(user.getPhone())
                .avatarUrl(user.getAvatarUrl())
                .department(user.getDepartment())
                .position(user.getPosition())
                .employeeId(user.getEmployeeId())
                .role(user.getRole().name().toLowerCase())
                .status(user.getStatus().name())
                .lastLoginAt(user.getLastLoginAt())
                .loginCount(user.getLoginCount())
                .createdAt(user.getCreatedAt())
                .updatedAt(user.getUpdatedAt())
                .build();
    }
}